package com.xmhmyh.generalframework.common.utils;

import com.alibaba.fastjson.JSON;
import com.xmhmyh.generalframework.common.SpringContextHolder;
import com.xmhmyh.generalframework.common.constants.QuartzConstants;
import com.xmhmyh.generalframework.common.enums.QuartzJobEnum;
import com.xmhmyh.generalframework.common.enums.ResponseCode;
import com.xmhmyh.generalframework.framework.exceptions.ManageExceptions;
import com.xmhmyh.generalframework.project.systool.entity.QuartzJob;
import lombok.SneakyThrows;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;

import java.util.Set;

/**
 * 定时任务工具类
 *
 * @author zzx
 */
public class QuartzUtils {

    /**
     * 创建定时任务
     *
     * @param quartzJob 任务实体类
     * @throws SchedulerException
     */
    public static void createJob(QuartzJob quartzJob, Scheduler scheduler) {
        // 通过反射获得类
        String beanName = quartzJob.getBeanName();
        Object bean = null;
        try {
            bean = SpringContextHolder.getBean(beanName);
        } catch (Exception e) {
            throw new ManageExceptions(ResponseCode.NOT_FOUND_BEAN);
        }
        Class<?> clazz = bean.getClass();
        //获得任务
        Long jobId = quartzJob.getId();
        String jobGroupName = quartzJob.getGroupName();
        JobDetail jobDetail = JobBuilder
                .newJob((Class<? extends Job>) clazz)
                .withIdentity(getJobKey(jobId, jobGroupName))
                .build();
        // 把job放进map中给QuartzFactory中execute方法传入的参数JobExecutionContext调用
        // jobDetail.getJobDataMap().put("scheduleJob", JSON.toJSONString(quartzJob));
        // 获得触发器
        CronTrigger trigger = TriggerBuilder
                .newTrigger()
                .withIdentity(getTriggerKey(jobId, jobGroupName))
                .withSchedule(CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression()))
                .build();
        try {
            //看此任务是否存在
            if (scheduler.checkExists(getJobKey(jobId, jobGroupName))) {
                scheduler.deleteJob(getJobKey(jobId, jobGroupName));
            }
            //告诉Quartz用这个触发器工作
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
            throw new ManageExceptions(ResponseCode.TASK_ERROR);
        }
    }

    /**
     * 获得TriggerKey
     *
     * @param jobId    任务id
     * @param jobGroup 任务组名
     * @return TriggerKey
     */
    public static TriggerKey getTriggerKey(Long jobId, String jobGroup) {
        return TriggerKey.triggerKey(QuartzConstants.TASK_CLASS_NAME + jobId, jobGroup);
    }

    /**
     * 获得jobKey
     *
     * @param jobId    任务id
     * @param jobGroup 任务组名
     * @return jobKey
     */
    public static JobKey getJobKey(Long jobId, String jobGroup) {
        return JobKey.jobKey(QuartzConstants.TASK_CLASS_NAME + jobId, jobGroup);
    }

    /**
     * 立即执行一次任务
     *
     * @param quartzJob 任务实体类
     * @throws SchedulerException
     */
    public static void run(QuartzJob quartzJob, Scheduler scheduler) throws SchedulerException {
        //获得jobKey
        JobKey jobKey = getJobKey(quartzJob.getId(), quartzJob.getGroupName());
        //根据jobKey立即执行一次任务
        scheduler.triggerJob(jobKey);
    }

    /**
     * 修改任务
     *
     * @param quartzJob 任务实体类
     * @throws SchedulerException
     */
    @SneakyThrows
    public static void update(QuartzJob quartzJob, Scheduler scheduler) {
        createJob(quartzJob, scheduler);
    }

    /**
     * 删除任务
     *
     * @param quartzJob 任务实体类
     * @throws SchedulerException
     */
    public static void delete(QuartzJob quartzJob, Scheduler scheduler) throws SchedulerException {
        //获得jobKey
        JobKey jobKey = getJobKey(quartzJob.getId(), quartzJob.getGroupName());
        //根据jobKey删除定时任务
        scheduler.deleteJob(jobKey);
    }

    /**
     * 暂停任务
     *
     * @param quartzJob 任务实体类
     * @throws SchedulerException
     */
    public static void pause(QuartzJob quartzJob, Scheduler scheduler) throws SchedulerException {
        //获得jobKey
        JobKey jobKey = getJobKey(quartzJob.getId(), quartzJob.getGroupName());
        //根据jobKey暂停任务
        scheduler.pauseJob(jobKey);
    }

    /**
     * 恢复任务
     *
     * @param quartzJob 任务实体类
     * @throws SchedulerException
     */
    public static void resume(QuartzJob quartzJob, Scheduler scheduler) throws SchedulerException {
        //获得jobKey
        JobKey jobKey = getJobKey(quartzJob.getId(), quartzJob.getGroupName());
        //根据jobKey恢复任务
        scheduler.resumeJob(jobKey);
    }

    /**
     * 清理任务
     *
     * @throws SchedulerException
     */
    public static void clear(Scheduler scheduler) throws SchedulerException {
        scheduler.clear();
    }

    /**
     * 展示所有任务
     *
     * @param scheduler
     * @throws SchedulerException
     */
    public static Set<JobKey> getJobs(Scheduler scheduler) throws SchedulerException {
        Set<JobKey> jobKeys = scheduler.getJobKeys(GroupMatcher.anyGroup());
        return jobKeys;
    }

}
